<!DOCTYPE html>
<html class="writer-html5" lang="en" data-content_root="../">
<head>
  <meta charset="utf-8" /><meta name="viewport" content="width=device-width, initial-scale=1" />

  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  <title>Federated Environment &mdash; SystemDS 3.3.0-dev documentation</title>
      <link rel="stylesheet" type="text/css" href="../static/pygments.css?v=80d5e7a1" />
      <link rel="stylesheet" type="text/css" href="../static/css/theme.css?v=19f00094" />

  
  <!--[if lt IE 9]>
    <script src="../static/js/html5shiv.min.js"></script>
  <![endif]-->
  
        <script src="../static/jquery.js?v=5d32c60e"></script>
        <script src="../static/_sphinx_javascript_frameworks_compat.js?v=2cd50e6c"></script>
        <script src="../static/documentation_options.js?v=492a8e1f"></script>
        <script src="../static/doctools.js?v=9a2dae69"></script>
        <script src="../static/sphinx_highlight.js?v=dc90522c"></script>
    <script src="../static/js/theme.js"></script>
    <link rel="index" title="Index" href="../genindex.html" />
    <link rel="search" title="Search" href="../search.html" />
    <link rel="next" title="Built-in Algorithms" href="algorithms_basics.html" />
    <link rel="prev" title="QuickStart" href="../getting_started/simple_examples.html" /> 
</head>

<body class="wy-body-for-nav"> 
  <div class="wy-grid-for-nav">
    <nav data-toggle="wy-nav-shift" class="wy-nav-side">
      <div class="wy-side-scroll">
        <div class="wy-side-nav-search" >

          
          
          <a href="../index.html" class="icon icon-home">
            SystemDS
          </a>
<div role="search">
  <form id="rtd-search-form" class="wy-form" action="../search.html" method="get">
    <input type="text" name="q" placeholder="Search docs" aria-label="Search docs" />
    <input type="hidden" name="check_keywords" value="yes" />
    <input type="hidden" name="area" value="default" />
  </form>
</div>
        </div><div class="wy-menu wy-menu-vertical" data-spy="affix" role="navigation" aria-label="Navigation menu">
              <p class="caption" role="heading"><span class="caption-text">Getting Started:</span></p>
<ul>
<li class="toctree-l1"><a class="reference internal" href="../getting_started/install.html">Install SystemDS</a></li>
<li class="toctree-l1"><a class="reference internal" href="../getting_started/simple_examples.html">QuickStart</a></li>
</ul>
<p class="caption" role="heading"><span class="caption-text">Guides</span></p>
<ul class="current">
<li class="toctree-l1 current"><a class="current reference internal" href="#">Federated Environment</a><ul>
<li class="toctree-l2"><a class="reference internal" href="#start-federated-worker">Start Federated worker</a></li>
<li class="toctree-l2"><a class="reference internal" href="#simple-aggregation-example">Simple Aggregation Example</a></li>
<li class="toctree-l2"><a class="reference internal" href="#multiple-federated-environments">Multiple Federated Environments</a></li>
<li class="toctree-l2"><a class="reference internal" href="#multi-tenant-federated-learning">Multi-tenant Federated Learning</a><ul>
<li class="toctree-l3"><a class="reference internal" href="#limitations">Limitations</a></li>
</ul>
</li>
</ul>
</li>
<li class="toctree-l1"><a class="reference internal" href="algorithms_basics.html">Built-in Algorithms</a></li>
<li class="toctree-l1"><a class="reference internal" href="python_end_to_end_tut.html">Python end-to-end tutorial</a></li>
</ul>
<p class="caption" role="heading"><span class="caption-text">API</span></p>
<ul>
<li class="toctree-l1"><a class="reference internal" href="../api/context/systemds_context.html">SystemDSContext</a></li>
<li class="toctree-l1"><a class="reference internal" href="../api/operator/algorithms.html">Algorithms</a></li>
<li class="toctree-l1"><a class="reference internal" href="../api/operator/node/matrix.html">Matrix</a></li>
<li class="toctree-l1"><a class="reference internal" href="../api/operator/node/frame.html">Frame</a></li>
<li class="toctree-l1"><a class="reference internal" href="../api/operator/node/list.html">List</a></li>
<li class="toctree-l1"><a class="reference internal" href="../api/operator/node/scalar.html">Scalar</a></li>
<li class="toctree-l1"><a class="reference internal" href="../api/operator/node/source.html">Source</a></li>
</ul>
<p class="caption" role="heading"><span class="caption-text">Internals API</span></p>
<ul>
<li class="toctree-l1"><a class="reference internal" href="../api/operator/operation_node.html">Operation Node</a></li>
<li class="toctree-l1"><a class="reference internal" href="../api/script_building/dag.html">Dag</a></li>
<li class="toctree-l1"><a class="reference internal" href="../api/script_building/script.html">Script</a></li>
<li class="toctree-l1"><a class="reference internal" href="../api/utils/converters.html">Converters</a></li>
<li class="toctree-l1"><a class="reference internal" href="../api/utils/helpers.html">Helpers</a></li>
</ul>

        </div>
      </div>
    </nav>

    <section data-toggle="wy-nav-shift" class="wy-nav-content-wrap"><nav class="wy-nav-top" aria-label="Mobile navigation menu" >
          <i data-toggle="wy-nav-top" class="fa fa-bars"></i>
          <a href="../index.html">SystemDS</a>
      </nav>

      <div class="wy-nav-content">
        <div class="rst-content">
          <div role="navigation" aria-label="Page navigation">
  <ul class="wy-breadcrumbs">
      <li><a href="../index.html" class="icon icon-home" aria-label="Home"></a></li>
      <li class="breadcrumb-item active">Federated Environment</li>
      <li class="wy-breadcrumbs-aside">
            <a href="../sources/guide/federated.rst.txt" rel="nofollow"> View page source</a>
      </li>
  </ul>
  <hr/>
</div>
          <div role="main" class="document" itemscope="itemscope" itemtype="http://schema.org/Article">
           <div itemprop="articleBody">
             
  <section id="federated-environment">
<h1>Federated Environment<a class="headerlink" href="#federated-environment" title="Link to this heading"></a></h1>
<p>The python SystemDS supports federated execution.
To enable this, each of the federated environments have to have
a running federated worker.</p>
<section id="start-federated-worker">
<h2>Start Federated worker<a class="headerlink" href="#start-federated-worker" title="Link to this heading"></a></h2>
<p>To start a federated worker, you first have to setup your environment variables.
A simple guide to do this is in the SystemDS <a class="reference external" href="https://github.com/apache/systemds/tree/main/bin/">Repository</a>.</p>
<p>If that is setup correctly simply start a worker using the following command.
Here the <code class="docutils literal notranslate"><span class="pre">8001</span></code> refer to the port used by the worker.</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">systemds</span> <span class="n">WORKER</span> <span class="mi">8001</span>
</pre></div>
</div>
</section>
<section id="simple-aggregation-example">
<h2>Simple Aggregation Example<a class="headerlink" href="#simple-aggregation-example" title="Link to this heading"></a></h2>
<p>In this example we use a single federated worker, and aggregate the sum of its data.</p>
<p>First we need to create some data for our federated worker to use.
In this example we simply use Numpy to create a <code class="docutils literal notranslate"><span class="pre">test.csv</span></code> file.</p>
<p>Currently we also require a metadata file for the federated worker.
This should be located next to the <code class="docutils literal notranslate"><span class="pre">test.csv</span></code> file called <code class="docutils literal notranslate"><span class="pre">test.csv.mtd</span></code>.
To make both the data and metadata simply execute the following</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="c1"># Python</span>
<span class="kn">import</span> <span class="nn">os</span>

<span class="kn">import</span> <span class="nn">numpy</span> <span class="k">as</span> <span class="nn">np</span>

<span class="k">if</span> <span class="ow">not</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">isdir</span><span class="p">(</span><span class="s2">&quot;temp&quot;</span><span class="p">):</span>
    <span class="n">os</span><span class="o">.</span><span class="n">mkdir</span><span class="p">(</span><span class="s2">&quot;temp&quot;</span><span class="p">)</span>
<span class="n">a</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">asarray</span><span class="p">([[</span><span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="p">,</span> <span class="mi">3</span><span class="p">],</span> <span class="p">[</span><span class="mi">4</span><span class="p">,</span> <span class="mi">5</span><span class="p">,</span> <span class="mi">6</span><span class="p">],</span> <span class="p">[</span><span class="mi">7</span><span class="p">,</span> <span class="mi">8</span><span class="p">,</span> <span class="mi">9</span><span class="p">]])</span>
<span class="n">np</span><span class="o">.</span><span class="n">savetxt</span><span class="p">(</span><span class="s2">&quot;temp/test.csv&quot;</span><span class="p">,</span> <span class="n">a</span><span class="p">,</span> <span class="n">delimiter</span><span class="o">=</span><span class="s2">&quot;,&quot;</span><span class="p">)</span>
<span class="k">with</span> <span class="nb">open</span><span class="p">(</span><span class="s2">&quot;temp/test.csv.mtd&quot;</span><span class="p">,</span> <span class="s2">&quot;w&quot;</span><span class="p">)</span> <span class="k">as</span> <span class="n">mtd</span><span class="p">:</span>
    <span class="n">mtd</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="s1">&#39;{ &quot;format&quot;:&quot;csv&quot;, &quot;header&quot;:false, &quot;rows&quot;:3, &quot;cols&quot;:3 }&#39;</span><span class="p">)</span>
</pre></div>
</div>
<p>After creating our data the federated worker becomes able to execute federated instructions.
The aggregated sum using federated instructions in python SystemDS is done as follows</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="c1"># Python</span>
<span class="kn">import</span> <span class="nn">logging</span>

<span class="kn">from</span> <span class="nn">systemds.context</span> <span class="kn">import</span> <span class="n">SystemDSContext</span>

<span class="c1"># Create a federated matrix</span>
<span class="c1"># Indicate the dimensions of the data:</span>
<span class="c1"># Here the first list in the tuple is the top left Coordinate,</span>
<span class="c1"># and the second the bottom left coordinate.</span>
<span class="c1"># It is ordered as [col,row].</span>
<span class="n">dims</span> <span class="o">=</span> <span class="p">([</span><span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">],</span> <span class="p">[</span><span class="mi">3</span><span class="p">,</span> <span class="mi">3</span><span class="p">])</span>

<span class="c1"># Specify the address + file path from worker:</span>
<span class="n">address</span> <span class="o">=</span> <span class="s2">&quot;localhost:8001/temp/test.csv&quot;</span>

<span class="k">with</span> <span class="n">SystemDSContext</span><span class="p">()</span> <span class="k">as</span> <span class="n">sds</span><span class="p">:</span>
    <span class="n">fed_a</span> <span class="o">=</span> <span class="n">sds</span><span class="o">.</span><span class="n">federated</span><span class="p">([</span><span class="n">address</span><span class="p">],</span> <span class="p">[</span><span class="n">dims</span><span class="p">])</span>
    <span class="c1"># Sum the federated matrix and call compute to execute</span>
    <span class="n">logging</span><span class="o">.</span><span class="n">info</span><span class="p">(</span><span class="n">fed_a</span><span class="o">.</span><span class="n">sum</span><span class="p">()</span><span class="o">.</span><span class="n">compute</span><span class="p">())</span>
    <span class="c1"># Result should be 45.</span>
</pre></div>
</div>
</section>
<section id="multiple-federated-environments">
<h2>Multiple Federated Environments<a class="headerlink" href="#multiple-federated-environments" title="Link to this heading"></a></h2>
<p>In this example we multiply matrices that are located in different federated environments.</p>
<p>Using the data created from the last example we can simulate
multiple federated workers by starting multiple ones on different ports.
Start with 3 different terminals, and run one federated environment in each.</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">systemds</span> <span class="n">WORKER</span> <span class="mi">8001</span>
<span class="n">systemds</span> <span class="n">WORKER</span> <span class="mi">8002</span>
<span class="n">systemds</span> <span class="n">WORKER</span> <span class="mi">8003</span>
</pre></div>
</div>
<p>Once all three workers are up and running we can leverage all three in the following example</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="c1"># Python</span>
<span class="kn">import</span> <span class="nn">logging</span>

<span class="kn">import</span> <span class="nn">numpy</span> <span class="k">as</span> <span class="nn">np</span>
<span class="kn">from</span> <span class="nn">systemds.context</span> <span class="kn">import</span> <span class="n">SystemDSContext</span>

<span class="n">addr1</span> <span class="o">=</span> <span class="s2">&quot;localhost:8001/temp/test.csv&quot;</span>
<span class="n">addr2</span> <span class="o">=</span> <span class="s2">&quot;localhost:8002/temp/test.csv&quot;</span>
<span class="n">addr3</span> <span class="o">=</span> <span class="s2">&quot;localhost:8003/temp/test.csv&quot;</span>

<span class="c1"># Create a federated matrix using two federated environments</span>
<span class="c1"># Note that the two federated matrices are stacked on top of each other</span>

<span class="k">with</span> <span class="n">SystemDSContext</span><span class="p">()</span> <span class="k">as</span> <span class="n">sds</span><span class="p">:</span>
    <span class="c1"># federated data on three locations</span>
    <span class="n">fed</span> <span class="o">=</span> <span class="n">sds</span><span class="o">.</span><span class="n">federated</span><span class="p">([</span><span class="n">addr1</span><span class="p">,</span> <span class="n">addr2</span><span class="p">,</span> <span class="n">addr3</span><span class="p">],</span> <span class="p">[</span>
        <span class="p">([</span><span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">],</span> <span class="p">[</span><span class="mi">3</span><span class="p">,</span> <span class="mi">3</span><span class="p">]),</span>
        <span class="p">([</span><span class="mi">3</span><span class="p">,</span> <span class="mi">0</span><span class="p">],</span> <span class="p">[</span><span class="mi">6</span><span class="p">,</span> <span class="mi">3</span><span class="p">]),</span>
        <span class="p">([</span><span class="mi">6</span><span class="p">,</span> <span class="mi">0</span><span class="p">],</span> <span class="p">[</span><span class="mi">9</span><span class="p">,</span> <span class="mi">3</span><span class="p">])])</span>
    <span class="c1"># local matrix to multiply with</span>
    <span class="n">loc</span> <span class="o">=</span> <span class="n">sds</span><span class="o">.</span><span class="n">from_numpy</span><span class="p">(</span><span class="n">np</span><span class="o">.</span><span class="n">array</span><span class="p">([</span>
        <span class="p">[</span><span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="p">,</span> <span class="mi">3</span><span class="p">,</span> <span class="mi">4</span><span class="p">,</span> <span class="mi">5</span><span class="p">,</span> <span class="mi">6</span><span class="p">,</span> <span class="mi">7</span><span class="p">,</span> <span class="mi">8</span><span class="p">,</span> <span class="mi">9</span><span class="p">],</span>
        <span class="p">[</span><span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="p">,</span> <span class="mi">3</span><span class="p">,</span> <span class="mi">4</span><span class="p">,</span> <span class="mi">5</span><span class="p">,</span> <span class="mi">6</span><span class="p">,</span> <span class="mi">7</span><span class="p">,</span> <span class="mi">8</span><span class="p">,</span> <span class="mi">9</span><span class="p">],</span>
        <span class="p">[</span><span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="p">,</span> <span class="mi">3</span><span class="p">,</span> <span class="mi">4</span><span class="p">,</span> <span class="mi">5</span><span class="p">,</span> <span class="mi">6</span><span class="p">,</span> <span class="mi">7</span><span class="p">,</span> <span class="mi">8</span><span class="p">,</span> <span class="mi">9</span><span class="p">]</span>
    <span class="p">]))</span>
    <span class="c1"># Multiply local and federated</span>
    <span class="n">ret</span> <span class="o">=</span> <span class="n">loc</span> <span class="o">@</span> <span class="n">fed</span>
    <span class="c1"># execute the lazy script and print</span>
    <span class="n">logging</span><span class="o">.</span><span class="n">info</span><span class="p">(</span><span class="n">ret</span><span class="o">.</span><span class="n">compute</span><span class="p">())</span>
</pre></div>
</div>
<p>The print should look like</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">[[</span><span class="mf">198.</span> <span class="mf">243.</span> <span class="mf">288.</span><span class="p">]</span>
 <span class="p">[</span><span class="mf">198.</span> <span class="mf">243.</span> <span class="mf">288.</span><span class="p">]</span>
 <span class="p">[</span><span class="mf">198.</span> <span class="mf">243.</span> <span class="mf">288.</span><span class="p">]]</span>
</pre></div>
</div>
<div class="admonition note">
<p class="admonition-title">Note</p>
<p>If it does not work, then double check
that you have:</p>
<p>a csv file, mtd file, and SystemDS Environment is set correctly.</p>
</div>
</section>
<section id="multi-tenant-federated-learning">
<h2>Multi-tenant Federated Learning<a class="headerlink" href="#multi-tenant-federated-learning" title="Link to this heading"></a></h2>
<p>SystemDS supports Multi-tenant Federated Learning, meaning that multiple
coordinators learn on shared federated workers. From another perspective,
the federated worker allows multiple coordinators to perform model training
simultaneously using the data from the respective federated site. This
approach enables the worker to operate in a server-like mode, providing
multiple tenants with the ability to learn on the federated data at the same
time. Tenant isolation ensures that tenant-specific intermediate results are
only accessible by the respective tenant.</p>
<section id="limitations">
<h3>Limitations<a class="headerlink" href="#limitations" title="Link to this heading"></a></h3>
<p>Since the coordinators are differentiated by their IP address in combination
with their process ID, the worker is not able to isolate coordinators which
share the same IP address and the same process ID. This occurs, for example,
when two coordinators are running behind a proxy (same IP address), where
both coordinators coincidentally have the same process ID.</p>
<p>A second limitation is showing up in networks using the Dynamic Host Protocol
(DHCP). Since the federated worker identifies the coordinator based on the
IP address, the worker does not re-identify the coordinator when its IP address
has changed, i.e., when DHCP renews its IP address.</p>
</section>
</section>
</section>


           </div>
          </div>
          <footer><div class="rst-footer-buttons" role="navigation" aria-label="Footer">
        <a href="../getting_started/simple_examples.html" class="btn btn-neutral float-left" title="QuickStart" accesskey="p" rel="prev"><span class="fa fa-arrow-circle-left" aria-hidden="true"></span> Previous</a>
        <a href="algorithms_basics.html" class="btn btn-neutral float-right" title="Built-in Algorithms" accesskey="n" rel="next">Next <span class="fa fa-arrow-circle-right" aria-hidden="true"></span></a>
    </div>

  <hr/>

  <div role="contentinfo">
    <p>&#169; Copyright 2024, Apache SystemDS.</p>
  </div>

  Built with <a href="https://www.sphinx-doc.org/">Sphinx</a> using a
    <a href="https://github.com/readthedocs/sphinx_rtd_theme">theme</a>
    provided by <a href="https://readthedocs.org">Read the Docs</a>.
   

</footer>
        </div>
      </div>
    </section>
  </div>
  <script>
      jQuery(function () {
          SphinxRtdTheme.Navigation.enable(true);
      });
  </script> 

</body>
</html>